package com.indexingsystem.system.oauth2;




import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

import com.indexingsystem.boss.entity.DhApiRole;
import com.indexingsystem.boss.entity.Roles;
import com.indexingsystem.system.service.DhApiRoleService;
import com.indexingsystem.system.service.IRolesService;
import com.indexingsystem.system.service.IUserRoleService;
import com.indexingsystem.system.web.model.Role;

import java.util.*;

/**
 * Created by Administrator on 2017/8/9.
 */
public class URLFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource,InitializingBean{
    //权限集合
    private Map<String, Collection<ConfigAttribute>> requestMap;
	@Autowired
	private  IRolesService iRolesService;
	@Autowired
	private  DhApiRoleService  dhApiRoleService;
	
	
    /**
     * 2、afterPropertiesSet方法，初始化bean的时候执行，
     * 可以针对某个具体的bean进行配置。afterPropertiesSet 必须实现 InitializingBean接口。
     * 实现 InitializingBean接口必须实现afterPropertiesSet方法。
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
       requestMap = loadAllResource();
    }

    /**
     * 该方法用作 RequestMap 的数据刷新。
     */
    public void refreshRequestData(){
        try {
            afterPropertiesSet();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 该方法目的是查询数据库里面的 String(代表URL),和该 URL 所需要的权限 Collection<ConfigAttribute>
     * @return
     */
   private Map<String,Collection<ConfigAttribute>> loadAllResource(){
	   
	   
        //声明一个缓存容器，缓存所有关于资源和权限的信息。
        Map<String , Collection<ConfigAttribute>> result = new HashMap<>();
            //开始封装当前资源对应的权限信息。
            Collection<ConfigAttribute> attrs = new ArrayList<>();
           //做测试的数据  当rest  需要两个角色能访问  和  获取token
           //正式模拟数据 查询那些API存在权限验证 
           List<DhApiRole> dhApiRoleList = dhApiRoleService.selectEndableRoleApi();
           List<Roles>  list= iRolesService.getdhRolesList();
           if(null!=list&&list.size()>0) {
        	   for(int i=0;i<list.size()-1;i++)
        		   attrs.add(new SecurityConfig(list.get(i).getRoleId().toString()));
        	   
        	   
        	        result.put("/rest",attrs);
        		  
           }
        return result;
    }

    /**
     * 每次用户登录时，都会调用该方法。你可以查看方法发里面的输出！！！
     * @param object
     * @return
     * @throws IllegalArgumentException
     */
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        String tempUrl = ((FilterInvocation)object).getRequestUrl();
        int endIndex = tempUrl.lastIndexOf("rest");
        String url = null;
        if(endIndex != -1){
            url = tempUrl.substring(0,endIndex);
            url=url+"rest";
        }
        return requestMap.get(url);
    }

    /**
     * getAllConfigAttributes方法如果返回了所有定义的权限资源，
     * Spring Security会在启动时校验每个ConfigAttribute是否配置正确，不需要校验直接返回null。
     * @return
     */
    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        Collection<ConfigAttribute> allConfigAttrs = new ArrayList<>();

        System.out.println("调用了 getAllConfigAttributes()方法！！！");

        Set<String> set = requestMap.keySet();

        for (String s : set) {
            allConfigAttrs.addAll(requestMap.get(s));
        }

        return allConfigAttrs;
    }

    /**
     * supports方法返回类对象是否支持校验，
     * web项目一般使用FilterInvocation来判断，或者直接返回true。
     * 在上面我们主要定义了两个权限码：
     * @param clazz
     * @return
     */
    @Override
    public boolean supports(Class<?> clazz) {
        return FilterInvocation.class.isAssignableFrom(clazz);
    }
}